﻿using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class ProblemManager: MonoBehaviour {


    public GameObject[] problemsPrefabs;
    public Catastrophe[] catastrophes;
    private Catastrophe currentCatasptrophe;
    public int problemsPerTurn = 4;
    public GameObject[] currentProblems;
    private int[] catastropheMonths;

    private int index = 0;

    public SceneFadeInOut fadePrefab;

    private Text dindinText;
    private RectTransform infraHold, healthHold, educationHold, securityHold;
    private RectTransform infraBar, healthBar, educationBar, securityBar;
    private Button openJournal, corruptButton;
    private GameObject corruptMenu, corruptModel;

    private RectTransform journal;
    private Text catastropheText, dataText, date;
    private Button closeJournal;
    //private RectTransform jinfraHold, jhealthHold, jeducationHold, jsecurityHold;
    private RectTransform jinfraBar, jhealthBar, jeducationBar, jsecurityBar;

    public AudioClip howdy;

    void Awake()
    {
        Status.Start();

        Transform tm = GameObject.Find("Canvas/TopMenu").transform;

        openJournal = tm.GetComponentInChildren<Button>();
        date = tm.parent.Find("Dates").GetComponent<Text>();
        Transform aux = tm.Find("Dindin");
        dindinText = aux.Find("Text").GetComponent<Text>();

        aux = tm.Find("Infra");
        infraHold = aux.Find("Hold").GetComponent<RectTransform>();
        infraBar = aux.Find("Bar").GetComponent<RectTransform>();

        aux = tm.Find("Health");
        healthHold = aux.Find("Hold").GetComponent<RectTransform>();
        healthBar = aux.Find("Bar").GetComponent<RectTransform>();

        aux = tm.Find("Education");
        educationHold = aux.Find("Hold").GetComponent<RectTransform>();
        educationBar = aux.Find("Bar").GetComponent<RectTransform>();

        aux = tm.Find("Security");
        securityHold = aux.Find("Hold").GetComponent<RectTransform>();
        securityBar = aux.Find("Bar").GetComponent<RectTransform>();

        corruptMenu = tm.parent.Find("CorruptMenu").gameObject;
        corruptButton = corruptMenu.GetComponentInChildren<Button>();

        tm = tm.parent.Find("Journal");
        journal = tm.GetComponent<RectTransform>();
        catastropheText = tm.Find("Catastrophe").GetComponent<Text>();

        aux = tm.Find("Infra");        
        jinfraBar = aux.Find("Bar").GetComponent<RectTransform>();
        aux = tm.Find("Health");        
        jhealthBar = aux.Find("Bar").GetComponent<RectTransform>();
        aux = tm.Find("Education");        
        jeducationBar = aux.Find("Bar").GetComponent<RectTransform>();
        aux = tm.Find("Security");        
        jsecurityBar = aux.Find("Bar").GetComponent<RectTransform>();

        dataText = tm.Find("Text").GetComponentInChildren<Text>();
        closeJournal = tm.GetComponentInChildren<Button>();
        
        tm = GameObject.Find("Cenario").transform;
        corruptModel = tm.Find("Corrupt").gameObject;

        date.gameObject.SetActive(false);
        openJournal.onClick.AddListener(OpenJournal);
        closeJournal.onClick.AddListener(CloseJournal);
        CloseJournal();
    }

    void Start()
    {
        InstantiateProblems();
        ShowHideCorrupt(false);
        catastropheMonths = new int[2];
        catastropheMonths[0] = Random.Range(1, 7);
        catastropheMonths[1] = Random.Range(7, 13);
        currentCatasptrophe = null;
    }

    public void ShowHideCorrupt(bool p)
    {
        StopAllCoroutines();
        corruptMenu.SetActive(p);
        corruptModel.SetActive(p);
        if (p)
            audio.PlayOneShot(howdy);
    }
    void InstantiateProblems()
    {
        if(currentProblems.Length > 0)
        {
            for (int i = 0; i < currentProblems.Length; i++)
            {
                Destroy(currentProblems[i]);
            }
            currentProblems = null;
        }

        currentProblems = new GameObject[problemsPerTurn];
        for (int i = 0; i < currentProblems.Length; i++)
        {
            currentProblems[i] = Instantiate(problemsPrefabs[Random.Range(0, problemsPrefabs.Length)]) as GameObject;
            currentProblems[i].SetActive(false);

            //Color c = new Color(Random.Range(0, 1f), Random.Range(0, 1f), Random.Range(0, 1f), 1);
            //c = Color.Lerp(c, Color.white, 0.2f);
            
            //foreach (Renderer ren in currentProblems[i].GetComponentsInChildren<Renderer>(true))
            //{
            //    ren.material.color = c;
            //}
        }
        index = -1;
        Next();
    }

    public void Next()
    {
        if(index >= 0 && index < currentProblems.Length)
            currentProblems[index].SetActive(false);
        
        index++;

        RefreshShownIndices();

        if (index < currentProblems.Length)
            currentProblems[index].SetActive(true);
        else
            StartCoroutine(EndOfDay());
    }

    private void RefreshShownIndices()
    {
        dindinText.text = Status.GetIndice(Status.Indices.Money).ToString();

        jinfraBar.sizeDelta = infraBar.sizeDelta = new Vector2(infraHold.sizeDelta[0] * (Status.GetIndice(Status.Indices.Infrastructure) / 100.0f), infraHold.sizeDelta[1]);
        jhealthBar.sizeDelta = healthBar.sizeDelta = new Vector2(healthHold.sizeDelta[0] * (Status.GetIndice(Status.Indices.Health) / 100.0f), healthHold.sizeDelta[1]);
        jeducationBar.sizeDelta = educationBar.sizeDelta = new Vector2(educationHold.sizeDelta[0] * (Status.GetIndice(Status.Indices.Education) / 100.0f), educationHold.sizeDelta[1]);
        jsecurityBar.sizeDelta = securityBar.sizeDelta = new Vector2(securityHold.sizeDelta[0] * (Status.GetIndice(Status.Indices.Security) / 100.0f), securityHold.sizeDelta[1]);

        if (currentCatasptrophe != null)
            catastropheText.text = currentCatasptrophe.text;
        else
            catastropheText.text = "";

        dataText.text = "Population: " + Status.GetIndice(Status.Indices.NPopulation);
    }
    IEnumerator EndOfDay()
    {
        SceneFadeInOut sfio = (Instantiate(fadePrefab.gameObject) as GameObject).GetComponent<SceneFadeInOut>();
        sfio.fadeSpeed = 1.0f;

        sfio.StartFadeOut();
        while (!sfio.FadeToBlack())
            yield return null;

        Status.CallEndOfTurn();
        if (currentCatasptrophe != null)
        {
            currentCatasptrophe.turnsCount++;
            bool a = false;
            foreach (Effect f in currentCatasptrophe.effect)
            {
                if (f.turnsInEffect >= currentCatasptrophe.turnsCount)
                    a = true;
            }
            if (!a)
                currentCatasptrophe = null;
        }
        RefreshShownIndices();
        if (Status.month == 1)
        {
            catastropheMonths[0] = Random.Range(1, 7);
            catastropheMonths[1] = Random.Range(7, 13);
        }

        
        System.Globalization.DateTimeFormatInfo mfi = new System.Globalization.DateTimeFormatInfo();
        date.text = "Year " + Status.year + "\n" + mfi.GetMonthName(Status.month).ToString();
        date.color = date.color - new Color(0,0,0,1);

        date.gameObject.SetActive(true);
        while (date.color.a <= 1)
        {
            date.color += new Color(0, 0, 0, 1) * Time.deltaTime;
            yield return null;
        }
        yield return new WaitForSeconds(0.75f);
        while (date.color.a > 0)
        {
            date.color -= new Color(0, 0, 0, 1) * Time.deltaTime;
            yield return null;
        }
        date.gameObject.SetActive(false);


        if (Status.month == catastropheMonths[0] || Status.month == catastropheMonths[1])
        {
            Catastrophe chosen = catastrophes[Random.Range(0, catastrophes.Length)];
            currentCatasptrophe = new Catastrophe();
            currentCatasptrophe.text = chosen.text;
            currentCatasptrophe.turnsCount = chosen.turnsCount;
            currentCatasptrophe.effect = new Effect[chosen.effect.Length];
            for (int i = 0; i < chosen.effect.Length; i++)
            {
                currentCatasptrophe.effect[i] = new Effect() { turnsInEffect = chosen.effect[i].turnsInEffect };
                currentCatasptrophe.effect[i].effect = chosen.effect[i].effect.Clone() as float[];
            }
            

            currentCatasptrophe.turnsCount = 0;
            Status.effectsInPlay.AddRange(currentCatasptrophe.effect);
            RefreshShownIndices();
            float totalTime = 0.5f, animationTime = totalTime;
            journal.localScale = Vector3.zero;
            journal.localRotation = Quaternion.identity;
            OpenJournal();
            while (animationTime > 0)
            {
                yield return null;
                animationTime -= Time.deltaTime;
                journal.localScale = Vector3.Lerp(Vector3.one,Vector3.zero,animationTime / totalTime);
                journal.Rotate(Vector3.forward, (1080 / totalTime) * Time.deltaTime);
            }
            journal.localScale = Vector3.one;
            journal.localRotation = Quaternion.identity;
            yield return new WaitForSeconds(5);
            CloseJournal();
        }

        sfio.StartFadeIn();
        while (!sfio.FadeToClear())
            yield return null;

        Destroy(sfio.gameObject);

        InstantiateProblems();
    }

    public void CheckCorrupt(PersonComportament pc)
    {
        int lowIndices = 0;
        if (Status.GetIndice(Status.Indices.Infrastructure) < 50.0f) lowIndices++;
        if (Status.GetIndice(Status.Indices.Health) < 50.0f) lowIndices++;
        if (Status.GetIndice(Status.Indices.Education) < 50.0f) lowIndices++;
        if (Status.GetIndice(Status.Indices.Security) < 50.0f) lowIndices++;

        float percentage = Mathf.Clamp(Status.GetIndice(Status.Indices.Corruption) * lowIndices, 0, 65);
        if(Status.GetIndice(Status.Indices.Money) > 80 && Random.Range(0, 100.0f) < percentage)
        {
            //ShowHideCorrupt(true);
            StartCoroutine(AppearCorrupt());

            corruptButton.onClick.RemoveAllListeners();
            corruptButton.onClick.AddListener( () => {
                ShowHideCorrupt(false);
                pc.StartGetOut();
                pc.GetComponent<ProblemHolder>().Close();
                float corr = (Status.GetIndice(Status.Indices.Corruption) + 10) / 5.0f;
                Status.effectsInPlay.Add(new Effect() { turnsInEffect = 6, effect = new float[] { -5 * (int)corr, -corr, -corr, -corr, -corr, 0, -10, 0 } });
                Status.effectsInPlay.Add(new Effect() { turnsInEffect = 1, effect = new float[] { -80, 40, 40, 40, 40, 10, 0, 0 } });
            });
        }
    }
    IEnumerator AppearCorrupt()
    {
        yield return new WaitForSeconds(2);
        ShowHideCorrupt(true);
    }

    void OpenJournal()
    {
        //RefreshShownIndices();
        journal.gameObject.SetActive(true);
    }
    void CloseJournal()
    {
        journal.gameObject.SetActive(false);
    }
}

